<?php

namespace yunj\app\admin\enum;

use think\facade\Db;
use yunj\app\admin\enum\route\RequestMethod;
use yunj\app\admin\model\AdminAuth;
use yunj\app\admin\model\AdminRoute;
use yunj\app\admin\model\AdminRouteRequest;
use yunj\app\admin\service\route\RouteService;
use yunj\app\admin\service\route\RouteRequestService;
use yunj\core\traits\RedisKey as RedisKeyTrait;

class RedisKey extends Enum {

    use RedisKeyTrait;

    // 后台路由数据（含正常和回收站数据）
    const ADMIN_ROUTES = 'admin.routes';

    // 后台有效（正常）的路由请求项数据集 根据base url获取
    const ADMIN_VALID_ROUTE_REQUEST_DATAS_BY_BASE_URL = 'admin.valid.route.request.datas.by.base.url:';

    // 后台页面基础地址数据 根据controller、action获取
    const ADMIN_PAGE_BASE_URL_BY_CONTROLLER_ACTION = 'admin.page.base.url.by.controller.action:';

    // 后台路由请求项数据 根据id获取
    const ADMIN_ROUTE_EQUEST_DATA_BY_ID = 'admin.route.request.data.by.id:';

    // 后台状态正常登录处理路由请求项数据
    const ADMIN_LOGIN_HANDLE_ROUTE_REQUEST_DATA = 'admin.login.handle.route.request.data';

    // 后台状态正常登出路由请求项数据
    const ADMIN_LOGOUT_ROUTE_REQUEST_DATA = 'admin.logout.route.request.data';

    // 后台状态正常权限数据 根据request_id获取
    const ADMIN_AUTH_DATA_BY_REQUEST_ID = 'admin.auth.data.by.request.id:';

    // 后台所有状态正常权限数据
    const ADMIN_ALL_AUTH_DATA = 'admin.all.auth.data';

    // 后台所有状态正常权限数据,不含demo数据
    const ADMIN_ALL_AUTH_DATA_BY_EXCLUDE_DEMO = 'admin.all.auth.data.by.exclude.demo';

    /**
     * 获取完整的key。示例：RedisKey::ADMIN_MEMBER_ID_BY_TOKEN()->setArgs($token)->key()
     * @return string
     */
    public function key(): string {
        return $this->_key();
    }

    public static function allEnumAttrs(): array {
        return [
            self::ADMIN_ROUTES => [
                'desc' => '后台路由数据（含正常和回收站数据）',
            ],
            self::ADMIN_VALID_ROUTE_REQUEST_DATAS_BY_BASE_URL => [
                'desc' => '后台有效（正常）的路由请求项数据集 根据base url获取',
                // key的后缀
                'keySuffixCall' => function (string $baseUrl) {
                    return $baseUrl;
                },
                // 原始值获取
                'valueCall' => function (string $baseUrl) {
                    $routes = RouteService::getValidRoutes();
                    $routeDatas = [];
                    foreach ($routes as $route) {
                        if ($route['base_url'] == $baseUrl) {
                            $routeDatas[$route['id']] = $route;
                        }
                    }
                    if (!$routeDatas) {
                        return [];
                    }
                    /** @var AdminRouteRequest $requestModel */
                    $requestModel = app(AdminRouteRequest::class);
                    $requests = $requestModel->getOwnRowsToArray([
                        ['route_id', 'in', array_keys($routeDatas)],
                        ['state', '=', State::NORMAL],
                    ]);
                    if (!$requests) {
                        return [];
                    }
                    $datas = [];
                    foreach ($requests as $request) {
                        $routeData = $routeDatas[$request['route_id']];
                        RouteService::handleFinalAttrData($request, $routeData);
                        if ($request['final_state'] != State::NORMAL) {
                            continue;
                        }
                        $datas[$request['id']] = RouteRequestService:: handleItemArgs($request) + [
                                'route_base_url' => $routeData['base_url'],
                                'route_desc' => $routeData['desc'],
                            ];
                    }
                    return $datas;
                }
            ],
            self::ADMIN_PAGE_BASE_URL_BY_CONTROLLER_ACTION => [
                'desc' => '后台页面基础地址数据 根据controller、action获取',
                // key的后缀
                'keySuffixCall' => function (string $controller, string $action) {
                    return md5($controller . '@' . $action);
                },
                // 原始值获取
                'valueCall' => function (string $controller, string $action) {
                    $routes = RouteService::getValidRoutes();
                    $ruleRoute = $controller . '@' . $action;
                    $routeDatas = [];
                    foreach ($routes as $route) {
                        if ($route['route'] == $ruleRoute) {
                            return $route['base_url'];
                        }
                    }
                    return '';
                }
            ],
            self::ADMIN_ROUTE_EQUEST_DATA_BY_ID => [
                'desc' => '后台路由请求项数据 根据id获取（含正常和回收站数据）',
                // key的后缀
                'keySuffixCall' => function ($id) {
                    return $id;
                },
                // 原始值获取
                'valueCall' => function ($id) {
                    $routes = RouteService::getAllRoutes();
                    $routeIds = array_keys($routes);
                    if (!$routeIds) {
                        return [];
                    }
                    /** @var AdminRouteRequest $model */
                    $model = app(AdminRouteRequest::class);
                    $request = $model->getOwnRowToArray([
                        ['id', '=', $id],
                        ['state', '<>', State::DELETED],
                        ['route_id', 'in', $routeIds],
                    ], ['id', 'desc', 'full_desc', 'route_id', 'method', 'require_params', 'enable_login_auth', 'if(system_key is null,0,1) as is_system', 'state']);
                    if (!$request) {
                        return [];
                    }
                    // 获取路由数据
                    $route = $routes[$request['route_id']];
                    $request += [
                        'route_rule' => $route['rule'],
                        'route_base_url' => $route['base_url'],
                    ];
                    // 处理路由请求属性最终值
                    RouteService::handleFinalAttrData($request, $route);
                    return $request;
                }
            ],
            self::ADMIN_LOGIN_HANDLE_ROUTE_REQUEST_DATA => [
                'desc' => '后台状态正常登录处理路由请求项数据',
                // 原始值获取
                'valueCall' => function () {
                    $routeRequestDatas = RouteRequestService::getValidRouteRequestDatasByBaseUrl(build_url('yunjAdminMemberLogin'));
                    if (!$routeRequestDatas) {
                        return [];
                    }
                    $requestRouteIds = array_keys($routeRequestDatas);

                    /** @var AdminRouteRequest $model */
                    $model = app(AdminRouteRequest::class);
                    $res = $model->getOwnRowToArray([
                        ['id', 'in', $requestRouteIds],
                        ['state', '=', State::NORMAL],
                        ['method', '=', RequestMethod::POST],
                    ]);
                    if (!$res) {
                        return [];
                    }
                    $resRoueteData = $routeRequestDatas[$res['id']];
                    $res += $resRoueteData;
                    return $res;
                }
            ],
            self::ADMIN_LOGOUT_ROUTE_REQUEST_DATA => [
                'desc' => '后台状态正常登出路由请求项数据',
                // 原始值获取
                'valueCall' => function () {
                    $routeRequestDatas = RouteRequestService::getValidRouteRequestDatasByBaseUrl(build_url('yunjAdminMemberLogout'));
                    if (!$routeRequestDatas) {
                        return [];
                    }
                    $requestRouteIds = array_keys($routeRequestDatas);

                    /** @var AdminRouteRequest $model */
                    $model = app(AdminRouteRequest::class);
                    $res = $model->getOwnRowToArray([
                        ['id', 'in', $requestRouteIds],
                        ['state', '=', State::NORMAL],
                    ], ['id', 'desc', 'route_id', 'method', 'require_params', 'enable_login_auth', 'if(system_key is null,0,1) as is_system']);
                    if (!$res) {
                        return [];
                    }
                    $resRoueteData = $routeRequestDatas[$res['id']];
                    $res += [
                        'route_desc' => $resRoueteData['desc'],
                        'route_base_url' => $resRoueteData['route_base_url'],
                    ];
                    return $res;
                }
            ],
            self::ADMIN_AUTH_DATA_BY_REQUEST_ID => [
                'desc' => '后台状态正常权限数据 根据request_id获取',
                // key的后缀
                'keySuffixCall' => function ($requestId) {
                    return $requestId;
                },
                // 原始值获取
                'valueCall' => function ($requestId) {
                    /** @var AdminAuth $model */
                    $model = app(AdminAuth::class);

                    $res = $model->getOwnRowToArray([
                        ['request_id', '=', $requestId],
                        ['state', '=', State::NORMAL],
                    ]);
                    return $res;
                }
            ],
            self::ADMIN_ALL_AUTH_DATA => [
                'desc' => '后台所有状态正常权限数据',
                // 原始值获取
                'valueCall' => function () {
                    /** @var AdminAuth $model */
                    $model = app(AdminAuth::class);
                    $res = $model->getOwnRowsToArray([['state', '=', State::NORMAL]], ['*'], ['sort' => 'asc']);
                    $res = array_column($res, null, 'key');
                    return $res;
                }
            ],
            self::ADMIN_ALL_AUTH_DATA_BY_EXCLUDE_DEMO => [
                'desc' => '后台所有状态正常权限数据,不含demo数据',
                // 原始值获取
                'valueCall' => function () {
                    /** @var AdminAuth $model */
                    $model = app(AdminAuth::class);
                    $res = $model->getOwnRowsToArray([
                        ['state', '=', State::NORMAL],
                        ['is_demo', '=', IsDemo::NO],
                    ], ['*'], ['sort' => 'asc']);
                    $res = array_column($res, null, 'key');
                    return $res;
                }
            ],
        ];
    }

}
